package org.jeecg.modules.simulator.model.line;

import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.simulator.Simulator;
import org.jeecg.modules.simulator.jsonot.NumPeopEnStationApiInfo;
import org.jeecg.modules.simulator.jsonot.ODProbabilityApiInfo;
import org.jeecg.modules.simulator.jsonot.RouteStation;
import org.jeecg.modules.simulator.loader.StationAddPersonNumData;
import org.jeecg.modules.simulator.model.MetroTrain;
import org.jeecg.modules.simulator.model.SceneDataType;
import org.jeecg.modules.simulator.model.SceneParam;
import org.jeecg.modules.simulator.model.line.assistance.Assistance;
import org.jeecg.modules.simulator.model.line.park.Parker;
import org.jeecg.modules.simulator.model.line.powersupplysection.PowerSupplySection;
import org.jeecg.modules.simulator.model.line.station.station.*;
import org.jeecg.modules.simulator.model.orbit.OrbitPath;
import lombok.Getter;
import lombok.Setter;
import org.jeecg.modules.simulator.model.orbit.OrbitPoint;
import org.jeecg.modules.simulator.model.person.Person;
import org.jeecg.modules.simulator.model.person.path.PersonPath;
import org.jeecg.modules.simulator.rooter.CaculateProject;
import org.jeecg.modules.simulator.util.UnitCache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.security.Key;
import java.time.LocalTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @program:
 * @description:线路场段运行
 * @author: renzhg
 * @create: 2024-08-29 11:11
 **/

public class Line implements Simulator {
    private static final Logger logger = LoggerFactory.getLogger(CaculateProject.class);
    @Getter
    @Setter
    String sceneCode;
    @Getter
    @Setter
    private String lineId;
    @Getter
    @Setter
    private String lineName;
    @Getter
    @Setter
    private String operationStatus;
    @Getter
    @Setter
    Map<String, Parker> parkerMap = new HashMap<>();//场段
    @Getter
    @Setter
    Map<String, Station> stationMap = new HashMap<>();
    @Getter
    @Setter
    Map<String, PowerSupplySection> powerSupplySectionMap = new HashMap<>();//供电区间
    @Getter
    @Setter
    Map<String, Assistance> assistanceMap = new HashMap<>();//线路辅助设施

    @Getter
    @Setter
    Map<String, Map<String, NumPeopEnStationApiInfo>> numPeopEnStationApiInfoMap = new HashMap<>();
    //    @Getter
//    @Setter
//    Map<String, Integer> netAllPersonSizePSecMap = new HashMap<>();
    @Setter
    Map<String, List<RouteStation>> t80RouteHisMap;

    @Getter
    OrbitPath upOrbitPath;//上行轨道

    @Getter
    OrbitPath downOrbitPath;//下行轨道


    public void setUpOrbitPath(OrbitPath upOrbitPath) {
        this.upOrbitPath = upOrbitPath;
        upOrbitPath.setUp(true);
    }

    public void setDownOrbitPath(OrbitPath downOrbitPath) {
        this.downOrbitPath = downOrbitPath;
        downOrbitPath.setUp(false);
    }

    //历史每秒进站人数,KEY:时间
//    @Setter
//   Map<String,Map<String, Integer>>  personInputStationPerPSecMap = new HashMap<>();
    //进站里面人数的OD概率
    @Setter
    Map<String, Map<String, List<ODProbabilityApiInfo>>> odProbabilityApiInfoMap = new HashMap<>();
    //key为routeid
    @Setter
    @Getter
    Map<String, PersonPath> route2PersonPathMap = new HashMap<>();

    @Setter
    @Getter
    //换乘站集合
    Map<String, TransferStation> transferStationMap = new HashMap<>();//换乘站集合

    @Getter
    @Setter
    Map<String, Station> stationNetMap = new HashMap<>();

    LineInfo lineInfo;
    LoadPerson loadPerson;

    public void initParkObit() {
        parkerMap.forEach((k, v) -> {
            String upStationName = upOrbitPath.getFirstPointName();
            if (v.getUpOut().getName().equals(upStationName)) {
                v.setWorkOrbitPath(upOrbitPath);
                v.setIsup(true);
            }

            String downStationName = downOrbitPath.getFirstPointName();
            if (v.getDownOut().getName().equals(downStationName)) {
                v.setWorkOrbitPath(downOrbitPath);
                v.setIsup(false);
            }
        });
    }

    public Boolean judgeUpDiction(OrbitPoint orbitPoint) {
        if (!orbitPoint.getBelongingType().equals("sect")) {
            return null;
        }
        boolean result = false;


        for (OrbitPoint orbitPoint1 : upOrbitPath) {
            if (orbitPoint1.getOrbitName().equals(orbitPoint.getOrbitName())) {
                return true;
            }
        }
        return result;


    }


    public void initPersonLoad() {
        SceneParam sceneParam = UnitCache.sceneParamMap.get(sceneCode);

        if (sceneParam.getSceneType().equals(SceneDataType.allDayHistoryData)) {
//            loadPerson = new LoadHistoryPerson(odProbabilityApiInfoMap, route2PersonPathMap, t80RouteHisMap, stationNetMap, transferStationMap);

            stationMap.forEach((k, v) -> {
                PersonCreater personCreater = new PersonCreater();
                Map<String, List<ODProbabilityApiInfo>> odProbabilityApiInfosMap = odProbabilityApiInfoMap.get(k);
                personCreater.setOdProbabilityApiInfosMap(odProbabilityApiInfosMap);
                personCreater.setRoute2PersonPathMap(route2PersonPathMap);
                personCreater.filterODProbabilityApiInfo();
                v.setPersonCreater(personCreater);
            });


        } else if (sceneParam.getSceneType().equals(SceneDataType.timePeriodHistoryData)) {


            loadPerson = new LoadHistoryPeriodTimePerson(odProbabilityApiInfoMap, route2PersonPathMap, t80RouteHisMap, stationNetMap, transferStationMap);


        }

    }

    @Override
    public LocalTime getCurrentTime() {
        return this.currentTime;
    }

    LocalTime currentTime;

    @Override
    public void UpdateCurrentTime(LocalTime currentTime) {
        this.currentTime = currentTime;
    }

    @Override
    public void nextTime(String now, Integer step) {
//        SceneParam sceneParam = UnitCache.sceneParamMap.get(sceneCode);

        stationMap.forEach((k, v) -> {
            if (v.isOpen()) {
                v.UpdateCurrentTime(this.getCurrentTime());
                v.nextTime(now, step);
            }
        });

        parkerMap.forEach((k, v) -> {
            v.nextTime(now, step);
        });

    }


}
